package com.shiyipicture.shiyipicturebackend.manager.upload;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.model.ciModel.persistence.CIObject;
import com.qcloud.cos.model.ciModel.persistence.ImageInfo;
import com.qcloud.cos.model.ciModel.persistence.ProcessResults;
import com.shiyipicture.shiyipicturebackend.config.CosClientConfig;
import com.shiyipicture.shiyipicturebackend.exception.BusinessException;
import com.shiyipicture.shiyipicturebackend.exception.ErrorCode;
import com.shiyipicture.shiyipicturebackend.manager.CosManager;
import com.shiyipicture.shiyipicturebackend.model.dto.file.UploadPictureResult;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;

@Slf4j
public abstract class FileManagerTemplate {
  @Resource
  private CosClientConfig cosClientConfig;

  @Resource
  private CosManager cosManager;

  /**
   * 模板方法 上传流程
   *
   * @param inputSource    输入源文件
   * @param uploadPathPrefix 上传路径前缀
   * @return
   */
  public final UploadPictureResult uploadPicture(Object inputSource, String uploadPathPrefix){
    validPicture(inputSource);
    String uuid = RandomUtil.randomString(16);
    String originalFileName = getOriginalFileName(inputSource);
    String uploadFileName = String.format("%s_%s.%s", DateUtil.formatDate(new Date()), uuid, FileUtil.getSuffix(originalFileName));
    String uploadPath = String.format("/%s/%s", uploadPathPrefix, uploadFileName);
    File file = null;
    try {
      file = File.createTempFile(uploadPath, null);
      processFile(inputSource,file);
      PutObjectResult putObjectResult = cosManager.putPictureObject(uploadPath,file);
      ImageInfo imageInfo = putObjectResult.getCiUploadResult().getOriginalInfo().getImageInfo();
      ProcessResults processResults = putObjectResult.getCiUploadResult().getProcessResults();
      List<CIObject> objectList = processResults.getObjectList();
      if (CollUtil.isNotEmpty(objectList)) {
        CIObject compressCiObject = objectList.get(0);
        CIObject thumbnailCiObject = compressCiObject;
        if (objectList.size() > 1) {
          thumbnailCiObject = objectList.get(1);
        }
        return buildResult(originalFileName,compressCiObject,thumbnailCiObject,imageInfo);
      }
      return getUploadPictureResult(originalFileName, uploadPath, file, imageInfo);
    } catch (IOException e) {
      log.error("图片上传处理失败",e);
      throw new BusinessException(ErrorCode.SYSTEM_ERROR,"上传失败");
    }finally {
      this.deleteTempFile(file);
    }
  }

  /**
   * 构造返回的图片对象
   * @param originalFileName
   * @param compressCiObject
   * @return
   */
  private UploadPictureResult buildResult(String originalFileName, CIObject compressCiObject,CIObject thumbnailCiObject,ImageInfo imageInfo) {
    UploadPictureResult uploadPictureResult = new UploadPictureResult();
    int picWidth = compressCiObject.getWidth();
    int picHeight = compressCiObject.getHeight();
    double picScale = NumberUtil.round(picWidth * 1.0 / picHeight, 2).doubleValue();
    uploadPictureResult.setUrl(cosClientConfig.getHost() + "/" + compressCiObject.getKey());
    uploadPictureResult.setPicName(originalFileName);
    uploadPictureResult.setPicSize(compressCiObject.getSize().longValue());
    uploadPictureResult.setPicWidth(picWidth);
    uploadPictureResult.setPicHeight(picHeight);
    uploadPictureResult.setPicScale(picScale);
    uploadPictureResult.setPicFormat(compressCiObject.getFormat());
    uploadPictureResult.setThumbnailUrl(cosClientConfig.getHost() + "/" + thumbnailCiObject.getKey());
    uploadPictureResult.setPicColor(imageInfo.getAve());
    return uploadPictureResult;
  }

  /**
   * 构造返回的图片对象
   * @param originalFileName
   * @param uploadPath
   * @param file
   * @param imageInfo
   * @return
   */
  private UploadPictureResult getUploadPictureResult(String originalFileName, String uploadPath, File file, ImageInfo imageInfo) {
    UploadPictureResult uploadPictureResult = new UploadPictureResult();
    int picWidth = imageInfo.getWidth();
    int picHeight = imageInfo.getHeight();
    double picScale = NumberUtil.round(picWidth * 1.0 / picHeight, 2).doubleValue();
    uploadPictureResult.setUrl(cosClientConfig.getHost() + "/" + uploadPath);
    uploadPictureResult.setPicName(originalFileName);
    uploadPictureResult.setPicSize(FileUtil.size(file));
    uploadPictureResult.setPicWidth(picWidth);
    uploadPictureResult.setPicHeight(picHeight);
    uploadPictureResult.setPicScale(picScale);
    uploadPictureResult.setPicFormat(imageInfo.getFormat());
    uploadPictureResult.setPicColor(imageInfo.getAve());
    return uploadPictureResult;
  }

  protected abstract void processFile(Object inputSource, File file) throws IOException;

  protected abstract String getOriginalFileName(Object inputSource);

  protected abstract void validPicture(Object inputSource);

  private void deleteTempFile(File file) {
    if (file == null) {
      return;
    }
    boolean delete = file.delete();
    if (!delete) {
      log.error("file delete error,filePath = {}",file.getAbsolutePath());
    }
  }
}
